//
// KkpParton.cxx
//
// Created by TB on 11/18/11.
// Copyright 2011 BNL. All rights reserved.
//

#include <algorithm>
#include <functional>
#include <iostream>
#include <iterator>
#include <map>

#include <TParticlePDG.h>
#include <TDatabasePDG.h>

#include "tppmc/KkpParton.h"

namespace tppmc {
   
   namespace kkp {
      
      
      int fromPdg(int KF) {
         
         // Convert quark KF codes to KKP
         
         // If we somehow fail then we are an UPQUARK?
         int retVal = UQUARK; 
         
         if(KF ==  1) retVal = DQUARK; 
         if(KF == -1) retVal = DBAR; 
         if(KF ==  2) retVal = UQUARK; 
         if(KF == -2) retVal = UBAR; 
         if(KF ==  3) retVal = SQUARK; 
         if(KF == -3) retVal = SBAR; 
         if(KF ==  4) retVal = CQUARK; 
         if(KF == -4) retVal = CBAR; 
         if(KF ==  5) retVal = BQUARK; 
         if(KF == -5) retVal = BBAR;
         if(KF ==  6) retVal = BQUARK; // Treat t as b 
         if(KF == -6) retVal = BBAR;
         if(KF == 21) retVal = GLUON; 
         
         return retVal; 
      }
      
      
      std::map<unsigned, int> Parton::mRelations;
      
      
      Parton::Parton(int i) {
         if(Valid(i)) {
            mKkp = i;
            mPdg = ToPdg(i);
         } // if
      }
      
      
      int Parton::PdgCode() const {
         return mPdg;
      }
      
      
      TParticlePDG* Parton::Pdg() const {
         return TDatabasePDG::Instance()->GetParticle(mPdg);
      }
      
      
      bool Parton::Valid(unsigned kkpCode) {
         if(mRelations.empty()) {
            unsigned kkpCodes[11] = {
               GLUON, UQUARK, UBAR, DQUARK, DBAR,
               SQUARK, SBAR, CQUARK, CBAR, BQUARK, BBAR
            };
            int pdgCodes[11] = {
               21, 2, -2, 1, -1, 3, -3, 4, -4, 5, -5
            };
            
            std::transform(kkpCodes, kkpCodes + 11,
                           pdgCodes,
                           std::inserter(mRelations, mRelations.begin()),
                           std::ptr_fun(&std::make_pair<unsigned, int>));
//            for(int i(0); i < 11; ++i) {
//               std::cout << kkpCodes[i] << " " << mRelations[kkpCodes[i]] << std::endl;
//            } // for
         } // if
         return mRelations.find(kkpCode) not_eq mRelations.end();
      }
      
      
      int Parton::ToPdg(unsigned i) {
         if(Valid(i)) return mRelations[i];
         return 0;
      }
      
} // namespace kkp

} // namespace tppmc
